package manage.controller;

import cn.hutool.core.util.IdUtil;
import commons.LayuiResult;
import commons.ResultBean;
import entity.Admin;
import entity.Role;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import manage.service.AdminService;
import manage.service.RoleService;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import vo.AdminVo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/admin")
@Api(tags = "管理员相关模块")
public class AdminController {

    @Autowired
    private AdminService adminService;

    @Autowired
    private RoleService roleService;

    /**
     * 根据用户名和密码登录
     * @param adminName
     * @param password
     * @return
     */
    @PostMapping("/login")
    @ApiOperation(value = "后台管理系统登录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "adminName",value = "用户名",required = true,dataType = "String"),
            @ApiImplicitParam(name = "password",value = "密码",required = true,dataType = "String"),
    })
    public ResultBean adminLogin(String adminName,String password){
        //1.获取subject
        Subject subject = SecurityUtils.getSubject();
        //2.封装用户数据
        UsernamePasswordToken token = new UsernamePasswordToken(adminName, password);
        //3.执行登录方法
        try {
            subject.login(token);
            Admin principal = (Admin) subject.getPrincipal();
            Session session = subject.getSession();
            session.setAttribute("admin", principal);
            return new ResultBean(200, "登陆成功");
        } catch (UnknownAccountException e) {
            //用户名不存在
            return new ResultBean(-1, e.getMessage());
        } catch (IncorrectCredentialsException e) {
            return new ResultBean(-1, e.getMessage());
        }catch (LockedAccountException e){
            return new ResultBean(-1,e.getMessage());
        }
    }


    /**
     * 加载所有用户列表
     * @param adminVo
     * @return
     */
    @GetMapping("/loadAllAdmins")
    @RequiresPermissions("admin:select")
    @ApiOperation(value = "加载所有管理员列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "adminName",value = "用户名",required = true,dataType = "String"),
            @ApiImplicitParam(name = "password",value = "密码",required = true,dataType = "String"),
    })
    public LayuiResult loadAllAdmins(AdminVo adminVo){
        LayuiResult layuiResult = adminService.loadAllAdmins(adminVo);
        return layuiResult;
    }

    /**
     * 根据用户ID查询角色并选中已拥有的角色
     */
    @GetMapping("/initRolesByAdminId")
    @RequiresPermissions("/admin:select")
    @ApiOperation(value = "根据管理员ID查询角色并选中已拥有的角色")
    @ApiImplicitParam(name = "adminId",value = "管理员ID",required = true,dataType = "Integer")
    public LayuiResult initRoleByAdminId(Integer adminId) {
        LayuiResult layuiResult = roleService.initRoleByAdminId(adminId);
        return layuiResult;
    }

    /**
     * 保存用户和角色
     * @param adminId
     * @param rIds
     * @return
     */
    @PostMapping("/saveAdminRoles")
    @RequiresPermissions("admin:update")
    @ApiOperation(value = "保存用户和角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "adminId",value = "管理员ID",required = true,dataType = "Integer"),
            @ApiImplicitParam(name = "rIds",value = "角色ID数组",required = true,dataType = "Array"),
    })
    public LayuiResult saveRolePermission(@Param("adminId") Integer adminId,@RequestParam(name = "rIds",required = false) Integer[] rIds) {
        if (null == rIds || rIds.length == 0){
            return LayuiResult.fail(-1, "分配角色不能为空");
        }
        int rows = roleService.saveUserRole(adminId, rIds);
        return LayuiResult.success(200, "分配成功");
    }


    /**
     * 加载管理员最大的排序码
     * @return
     */
    @GetMapping("/loadAdminMaxOrderNum")
    @ApiOperation(value = "加载管理员最大的排序码")
    public Map<String,Object> loadAdminMaxOrderNum(){
        Map<String,Object> map = new HashMap<>();
        Integer orderNum = adminService.loadAdminMaxOrderNum();
        //排序码加1
        map.put("orderNum",orderNum+1);
        return map;
    }

    /**
     * 添加管理员
     * @param adminVo
     * @return
     */
    @PostMapping("/addAdmin")
    @RequiresPermissions("admin:add")
    @ApiOperation(value = "添加管理员")
    @ApiImplicitParam(name = "adminVo",value = "用户",required = true,dataType = "AdminVo")
    public LayuiResult addAdmin(AdminVo adminVo){
        try {
            //判断用户名是否存在
            Admin admin = adminService.queryByUsername(adminVo.getUsername());
            if (admin != null){
                return LayuiResult.fail(-1,"该用户名已存在");
            }
            adminVo.setType(1); //设置管理员类型为普通类型
            String salt= IdUtil.simpleUUID().toUpperCase();
            adminVo.setSalt(salt);//设置盐
            String password = new SimpleHash("MD5", adminVo.getPassword(), salt, 1).toString();
            adminVo.setPassword(password);
            adminService.addAdmin(adminVo);
            return LayuiResult.success(200,"添加成功");
        } catch (Exception e) {
            e.printStackTrace();
            return LayuiResult.fail(-1,"添加失败");
        }
    }


    /**
     * 重置管理员的密码为6个1
     * @param id
     * @return
     */
    @PostMapping("/resetPassword")
    @RequiresPermissions("admin:reset")
    @ApiOperation(value = "重置管理员的密码为6个1")
    @ApiImplicitParam(name = "id",value = "管理员ID",required = true,dataType = "Integer")
    public LayuiResult resetPassword(Integer id){
        int result = adminService.resetPassword(id);
        if (result > 0){
            return LayuiResult.success(200,"重置密码成功");
        }else {
            return LayuiResult.fail(-1,"重置密码失败");
        }
    }


    /**
     * 锁定管理员
     * @param id
     * @return
     */
    @PostMapping("/lockAdmin")
    @RequiresPermissions("admin:lock")
    @ApiOperation(value = "根据管理员ID锁定管理员")
    @ApiImplicitParam(name = "id",value = "管理员ID",required = true,dataType = "Integer")
    public LayuiResult lockAdmin(Integer id){
        int result = adminService.lock(id);
        if (result > 0){
            return LayuiResult.success(200,"账户锁定成功");
        }else {
            return LayuiResult.fail(-1,"账户锁定失败");
        }
    }


    /**
     * 解锁管理员
     * @param id
     * @return
     */
    @PostMapping("/unlockAdmin")
    @RequiresPermissions("admin:unlock")
    @ApiOperation(value = "根据管理员ID解锁管理员")
    @ApiImplicitParam(name = "id",value = "管理员ID",required = true,dataType = "Integer")
    public LayuiResult unlockAdmin(Integer id){
        int result = adminService.unlock(id);
        if (result > 0){
            return LayuiResult.success(200,"账户解锁成功");
        }else {
            return LayuiResult.fail(-1,"账户解锁失败");
        }
    }
}
